package com.example.threebuttonapp;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.media.MediaPlayer;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import android.content.SharedPreferences;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import android.app.PendingIntent;

/**
 * 主Activity类
 * 实现打呼噜检测和震动提醒功能
 */
public class MainActivity extends AppCompatActivity {
    // 日志标签
    private static final String TAG = "MainActivity";
    
    // 按钮文本常量
    private static final String BUTTON1_TEXT = "开始检测";
    private static final String BUTTON1_STOP_TEXT = "停止检测";
    private static final String BUTTON2_TEXT = "按钮2被点击了";
    private static final String BUTTON3_TEXT = "按钮3被点击了";
    
    // 权限请求码
    private static final int PERMISSION_REQUEST_CODE = 1;
    
    // 震动相关常量
    private static final int MAX_VIBRATION_AMPLITUDE = 255;  // 最大震动强度
    
    // 音频录制相关常量
    private static final int SAMPLE_RATE = 44100;            // 采样率
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;  // 单声道
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; // 16位PCM格式
    private static final int BUFFER_SIZE = SAMPLE_RATE/10;//100ms
    // private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(    // 缓冲区大小
    //             SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT);
    

    // 新增成员变量
    static int vibrationDuration = 4000; // 默认震动时长
    private int vibrationCooldown = 3000;  // 默认震动冷却时间
    private int recordingTime = 10;         // 默认录制时间
    private double volumeRatio = 1.5;       // 默认音量均值比例
    static int vibrationCount = 0; // 用于跟踪连续触发震动的次数
    static boolean isVibrating = false; // 表示是否正在震动
    private TextView vibrationCountTextView; // 用于显示连续震动次数
    static boolean isSoundEnabled = true; // 默认启用铃声
    // 成员变量
    private AudioRecord audioRecord;     // 音频录制器
    private boolean isRecording = false; // 是否正在录制
    private Thread recordingThread;      // 录制线程
    private long startTime = 0;          // 开始时间
    private Button button1;              // 开始/停止按钮
    private Vibrator vibrator;           // 震动器
    private long lastVibrationTime = 0;  // 上次震动时间
    private short[] audioBuffers; // 用于存储音频数据的数组
    private int audioBufferCount = 0; // 当前存储的音频数据数量
    private static final int ONE_SECOND_SAMPLES = SAMPLE_RATE;  // 一秒的采样数量
    private short[] secondBuffer;  // 存储1秒数据的缓冲区
    private int secondBufferIndex = 0;  // 当前填充位置
    private GraphView graph;
    private LineGraphSeries<DataPoint> series;
    private AtomicInteger graphX = new AtomicInteger(0); // 用于跟踪时间点
    private TextView ratioTextView; // 新增成员变量
    static MediaPlayer alarmPlayer; // 新增变量，用于播放铃声
    private static final int MAX_DATA_POINTS = 100; // 最大数据点数量
    private DataPoint[] dataPoints = new DataPoint[MAX_DATA_POINTS]; // 存储数据点的数组
    private int dataPointIndex = 0; // 当前数据点索引
    private int maxX = 2100000000; // 最大X值
    private double maxY = 0; // 最大X值
    /**
     * Activity创建时的初始化
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent vibrationIntent = new Intent(this, VibrationService.class);
        Log.d(TAG, "Starting VibrationService");
        startService(vibrationIntent);


        // 初始化震动器
        vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);

        // 初始化 TextView
        ratioTextView = findViewById(R.id.ratioTextView); // 获取比率 TextView 引用
        vibrationCountTextView = findViewById(R.id.vibrationCountTextView); // 获取震动次数 TextView 引用

        // 初始化铃声播放器
        alarmPlayer = MediaPlayer.create(this, R.raw.alarm_sound); // 假设您有一个名为 alarm_sound 的音频文件
        // alarmPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);

        try {
            setupButtons();    // 设置按钮
            checkPermissions();// 检查权限
            setupGraph();      // 设置 GraphView
        } catch (Exception e) {
            Log.e(TAG, "Error in onCreate", e);
        }
    }

    /**
     * 检查并请求录音权限
     */
    private void checkPermissions() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.RECORD_AUDIO},
                    PERMISSION_REQUEST_CODE);
        }
    }

    /**
     * 初始化并设置按钮点击事件
     */
    private void setupButtons() {
        button1 = findViewById(R.id.button1);
        Button button2 = findViewById(R.id.button2);
        Button button3 = findViewById(R.id.button3);

        // 设置按钮1（开始/停止检测）
        if (button1 != null) {
            button1.setOnClickListener(v -> toggleRecording());
        } else {
            Log.e(TAG, "Button1 not found");
        }

        // 设置按钮2（进入设置页面）
        if (button2 != null) {
            button2.setOnClickListener(v -> {
                Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
                // 传递当前参数
                intent.putExtra("vibrationDuration", vibrationDuration);
                intent.putExtra("vibrationCooldown", vibrationCooldown);
                intent.putExtra("recordingTime", recordingTime);
                intent.putExtra("volumeRatio", volumeRatio);
                startActivityForResult(intent, 1); // 启动设置页面
            });
        } else {
            Log.e(TAG, "Button2 not found");
        }

        // 设置按钮3
        if (button3 != null) {
            button3.setOnClickListener(v -> showToast("volumeRatio: " + volumeRatio + ", isSoundEnabled: " + isSoundEnabled));
        } else {
            Log.e(TAG, "Button3 not found");
        }
    }

    /**
     * 设置 GraphView
     */
    private void setupGraph() {
        graph = findViewById(R.id.graph);
        series = new LineGraphSeries<>();
        graph.addSeries(series);
        graph.getViewport().setXAxisBoundsManual(true);
        graph.getViewport().setMinX(0);
        graph.getViewport().setMaxX(100); // 设置最大时间范围为100
        graph.getViewport().setYAxisBoundsManual(true);
        graph.getViewport().setMinY(0); // 设置最小Y值
        graph.getViewport().setMaxY(0); // 设置最大Y值
        graph.getGridLabelRenderer().setPadding(100); // 设置边距
    }

    /**
     * 切换录音状态（开始/停止）
     */
    private void toggleRecording() {
        if (!isRecording) {
            startRecording1();
        } else {
            stopRecording();
        }
    }

    /**
     * 开始录音和检测
     */
    private void startRecording1() {
        // 检查录音权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
                != PackageManager.PERMISSION_GRANTED) {
            showToast("需要录音权限");
            return;
        }

        try {
            // 初始化AudioRecord
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, BUFFER_SIZE);

            // 检查初始化状态
            if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
                showToast("无法初始化录音器");
                return;
            }

            // 更新状态和UI
            isRecording = true;
            startTime = System.currentTimeMillis();
            button1.setText(BUTTON1_STOP_TEXT);

            // 启动录音线程
            recordingThread = new Thread(() -> {
                short[] buffer = new short[BUFFER_SIZE];
                audioRecord.startRecording();

                while (isRecording) {
                    int readSize = audioRecord.read(buffer, 0, BUFFER_SIZE);
                    
                    if (readSize >= BUFFER_SIZE) {
                        if(isVibrating){
                            continue;
                        }
                        detectSnoring(buffer, readSize);
                        updateGraph(buffer, readSize); // 更新图表
                    }
                }
            });
            recordingThread.start();
            showToast("开始检测");
        } catch (Exception e) {
            Log.e(TAG, "Error starting recording", e);
            showToast("启动录音失败");
        }
    }

    /**
     * 停止录音和检测
     */
    private void stopRecording() {
        try {
            // 停止录音
            isRecording = false;
            if (audioRecord != null) {
                audioRecord.stop();
                audioRecord.release();
                audioRecord = null;
            }
            
            // 等待录音线程结束
            if (recordingThread != null) {
                recordingThread.join();
                recordingThread = null;
            }
            
            // 清空录制缓存
            audioBuffers = null;
            audioBufferCount = 0;

            // 清空图表
            series.resetData(new DataPoint[0]); // 清空图表数据

            // 重置 graphX 的值为 0
            graphX.set(0); // 将 graphX 重置为 0

            // 清零连续震动次数
            vibrationCount = 0; // 重置震动计数 
            runOnUiThread(() -> vibrationCountTextView.setText("连续震动次数: " + vibrationCount));

            // 显示检测时长
            long duration = System.currentTimeMillis() - startTime;
            String durationText = String.format("检测时间：%d分%d秒",
                    duration / 1000 / 60,
                    (duration / 1000) % 60);
            showToast(durationText);
            
            // 停止铃声播放
            if (alarmPlayer != null) {
                alarmPlayer.stop(); // 停止铃声播放
                alarmPlayer.prepare(); // 准备 MediaPlayer 以便下次播放
            }

            // 恢复按钮文本
            button1.setText(BUTTON1_TEXT);
        } catch (Exception e) {
            Log.e(TAG, "Error stopping recording", e);
        }
    }

    /**
     * 检测打呼噜的声音并触发震动
     * @param buffer 音频数据缓冲区
     * @param readSize 实际读取的数据大小
     */
    private void detectSnoring(short[] buffer, int readSize) {
        // 初始化音频缓冲区
        if (audioBuffers == null) {
            audioBuffers = new short[ONE_SECOND_SAMPLES * recordingTime]; // 根据录制时间和采样率初始化数组
            audioBufferCount = 0; // 初始化计数器
        }

        // 将当前 buffer 的拷贝添加到 audioBuffers
        for (int i = 0; i < readSize; i++) {
            if (audioBufferCount < audioBuffers.length) {
                audioBuffers[audioBufferCount++] = buffer[i]; // 添加到音频缓冲区
            }
        }

        // 检查是否已经录制了指定的音频时间
        if (audioBufferCount < ONE_SECOND_SAMPLES * recordingTime) {
            return; // 如果没有足够的数据，直接返回
        }

        // 找到最大声点的数量，限制为10个
        int maxLoudestCount = Math.min(audioBufferCount / 3, 10); // 找到的最大声点数量
        List<Integer> loudestIndices = new ArrayList<>();

        for (int i = 0; i < audioBufferCount; i++) {
            if (loudestIndices.size() < maxLoudestCount || Math.abs(audioBuffers[i]) > Math.abs(audioBuffers[loudestIndices.get(loudestIndices.size() - 1)])) {
                if (loudestIndices.size() == maxLoudestCount) {
                    loudestIndices.remove(loudestIndices.size() - 1); // 移除最小的
                }
                loudestIndices.add(i);
                loudestIndices.sort((a, b) -> Double.compare(Math.abs(audioBuffers[b]), Math.abs(audioBuffers[a]))); // 降序
            }
        }

        // 计算所有最大声点前100ms后100ms的音量均值
        double totalVolumeWithLoudest = 0;
        int countWithLoudest = 0;

        for (int index : loudestIndices) {
            int start = Math.max(0, index - 100 * SAMPLE_RATE / 1000); // 前100ms
            int end = Math.min(audioBufferCount, index + 100 * SAMPLE_RATE / 1000); // 后100ms
            for (int k = start; k < end; k++) {
                totalVolumeWithLoudest += Math.abs(audioBuffers[k]);
                countWithLoudest++;
            }
        }
        double averageVolumeWithLoudest = countWithLoudest > 0 ? totalVolumeWithLoudest / countWithLoudest : 0; // 防止除以零

        // 计算不包括所有最大声点及其前后100ms的音量均值作为环境音量
        double totalVolumeEnvironment = 0;
        int countEnvironment = 0;

        for (int i = 0; i < audioBufferCount; i++) {
            boolean isLoudestPoint = loudestIndices.contains(i);
            boolean isWithin100ms = false;

            for (int index : loudestIndices) {
                if (i >= index - 100 * SAMPLE_RATE / 1000 && i <= index + 100 * SAMPLE_RATE / 1000) {
                    isWithin100ms = true;
                    break;
                }
            }

            if (!isLoudestPoint && !isWithin100ms) { // 排除最大声点及其前后100ms
                totalVolumeEnvironment += Math.abs(audioBuffers[i]);
                countEnvironment++;
            }
        }
        double averageVolumeEnvironment = countEnvironment > 0 ? totalVolumeEnvironment / countEnvironment : 0; // 防止除以零

        // 计算比率
        if (averageVolumeEnvironment > 0) { // 确保不为零
            double ratio = averageVolumeWithLoudest / (averageVolumeEnvironment);
            runOnUiThread(() -> ratioTextView.setText("比率: " + ratio)); // 在主线程中更新 TextView 显示比率
        } else {
            Log.e(TAG, "Average volume environment is zero, cannot calculate ratio.");
        }

        // 如果最大点音量均值比指定比例的环境音量大一定比例，则震动
        if ((averageVolumeWithLoudest / averageVolumeEnvironment) > volumeRatio) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastVibrationTime >= vibrationCooldown) {
                isVibrating = true;
                vibrationCount++;
                // 增加震动计数
                Log.d(TAG, "Vibration count: " + vibrationCount); // 输出震动计数

                // 更新震动次数显示
                runOnUiThread(() -> vibrationCountTextView.setText("连续震动次数: " + vibrationCount));
                // vibrator.vibrate(VibrationEffect.createOneShot(500, 255)); // 让手机进行普通震动
                
                
                lastVibrationTime = currentTime;
                try {
                    Thread.sleep(vibrationDuration+1000);
                    isVibrating = false;
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 恢复中断状态
                }
            }
        } else {
            // 如果没有触发震动，重置计数器
            vibrationCount = 0;
            runOnUiThread(() -> vibrationCountTextView.setText("连续震动次数: " + vibrationCount)); // 更新显示
        }
        // 重置缓冲区，准备收集下一秒的数据
        audioBufferCount = 0;
    }

    private void updateGraph(short[] buffer, int readSize) {
        // 计算音量
        double totalVolume = 0;
        for (int i = 0; i < readSize; i++) {
            totalVolume += Math.abs(buffer[i]);
        }
        double averageVolume = totalVolume / readSize;

        // 确保音量不超过300
        // if (averageVolume > 300) {
        //     averageVolume = 300;
        // }

        // 使用 final 变量来存储 averageVolume
        final double finalAverageVolume = averageVolume;

        // 更新图表
        runOnUiThread(() -> {
            int currentX = graphX.getAndIncrement(); // 获取当前值并增加
            maxY = Math.max(maxY, finalAverageVolume);
            graph.getViewport().setMaxY(maxY);
            // 检查 currentX 是否溢出2,147,483,647
            if (currentX > 36000) {//200000000s 
                currentX = 0; // 重置为0
                series.resetData(new DataPoint[0]); // 清空图表数据
                graphX.set(0); // 重置 graphX
            }

            series.appendData(new DataPoint(currentX, finalAverageVolume), true, 100); // 添加数据点
            if (currentX > 100) {
                graph.getViewport().setMinX(currentX - 100); // 移动视口
                graph.getViewport().setMaxX(currentX);
            }
        });
    }   

    /**
     * 显示Toast消息
     * @param message 要显示的消息内容
     */
    private void showToast(String message) {
        try {
            if (message != null && !isFinishing()) {
                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Log.e(TAG, "Error showing toast", e);
        }
    }

    /**
     * Activity销毁时的清理工作
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 确保在Activity销毁时停止录音
        if (isRecording) {
            stopRecording();
        }
        // 释放铃声播放器资源
        if (alarmPlayer != null) {
            alarmPlayer.release();
            alarmPlayer = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == RESULT_OK) {
            if (data != null) {
                vibrationDuration = data.getIntExtra("vibrationDuration", 4000); // 默认值
                vibrationCooldown = data.getIntExtra("vibrationCooldown", 3000); // 默认值
                recordingTime = data.getIntExtra("recordingTime", 10); // 默认值
                volumeRatio = data.getDoubleExtra("volumeRatio", 1.5); // 默认值

                // 读取铃声开关状态
                SharedPreferences sharedPreferences = getSharedPreferences("app_settings", MODE_PRIVATE);
                isSoundEnabled = sharedPreferences.getBoolean("sound_enabled", false); // 默认启用铃声
                // 根据 isSoundEnabled 决定是否播放铃声
                if (isSoundEnabled) {
                    // 播放铃声的逻辑
                }
            }
        }
    }

} 